package com.guiji.text2video.job.task;

import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RuntimeUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.guiji.text2video.common.redis.service.RedisService;
import com.guiji.text2video.job.domain.NewsSimplePushVO;
import com.guiji.text2video.job.domain.Text2videoJob;
import com.guiji.text2video.job.util.DingUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/**
 * @Copyright (C), 2018-2021
 * @FileName: PushHistoryTimingTask
 * @Author: scl
 * @Date: 2021/8/30 12:28
 * @Description: 三国水浒推送类
 */

@Component("history")
public class PushHistoryTimingTask {

    private static final Logger logger = LoggerFactory.getLogger(PushHistoryTimingTask.class);

    @Autowired
    private RedisService redisService;

    @Autowired
    PushTask pushTask;

    /**
     * @descp: redis开头，channel，cookie
     * @param: sanguo shuihu honglou xiyou
     * <p>
     * <p>
     * history.push('sanguo','陪你看三国','shenhualishimingzhupingshuo')
     * history.push('shuihu','最新水浒故事','huishuolishi')
     * history.push('honglou','红楼人物故事评说','hongloumeng')
     * @Author: scl
     * @Date: 2021/11/12 15:44
     */
    public void push(String redisfor, String channel, String cookie) {
        Collection<String> collections = redisService.keys(redisfor + "*");
        logger.info("周期任务，获取历史任务:{}个数：{}", redisfor, collections.size());
        if (collections.size() == 0) {
            return;
        }
        List<String> list = new ArrayList<>();
        int count = 0;
        for (String key : collections) {
            if (count == 1) {
                break;
            }
            list.add(redisService.getCacheObject(key));
            redisService.deleteObject(key);
            count++;
        }
        //保证不重复list只取第一个，立马删掉原有集合数据（多个任务下不重复）
        Iterator iter = list.iterator();

        while (iter.hasNext()) {
            String newsSimplePushVO = (String) iter.next();
            NewsSimplePushVO nspVO = JSON.parseObject(newsSimplePushVO, new TypeReference<NewsSimplePushVO>() {
            });
            String title = nspVO.getTitle();
            if (title.length() > 100) {
                title = title.substring(0, 99);
            }
            nspVO.setTitle(title);
            nspVO.setChannel(channel);
            nspVO.setUsername(cookie);

            String fileName = FileNameUtil.getName(URLUtil.decode(nspVO.getPath()));
            String secondName = fileName.substring(0, 32) + ".mp4";
            //下载文件
            String wgetCmd = "wget " + URLUtil.encode(nspVO.getPath()) + " -O /data/hdd/" + secondName;
            RuntimeUtil.execForStr(wgetCmd);
            //传输文件
            String saveFile = "/data/hdd/" + secondName;
            long fileSizeBytes = new File(saveFile).length();
            String scpCmd = "scp -i /data/text2video/duix.pem  " + saveFile + " centos@44.236.176.10:/home/centos/news_video";
            String result = RuntimeUtil.execForStr(scpCmd);

            int counter = 0;
            while (true) {
                if (counter > 5) {
                    logger.info("scp命令失败停顿10秒,重试：6,终止方法，依然失败：{}", scpCmd);
                    return;
                }
                if (null == result || result.contains("No such file or directory")) {
                    break;
                }
                counter++;
                logger.info("scp命令失败停顿10秒,重试：{},命令：{}", counter, scpCmd);
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                result = RuntimeUtil.execForStr(scpCmd);
            }


            //删除缓存文件
            RuntimeUtil.execForStr("rm -f " + saveFile);
            //修改路径
            nspVO.setPath("/home/centos/news_video/" + secondName);
            nspVO.setTimeout(pushTask.getTimeoutSecond(fileSizeBytes));
            String url = "http://44.236.176.10:5556/api/upload";
            HttpResponse httpResponse = null;
            logger.info("发起推送请求,对象:{}", JSONUtil.parseObj(nspVO).toString());
            try {
                httpResponse = HttpRequest.post(url).timeout(7200000).body(JSONUtil.parseObj(nspVO).toString()).executeAsync();
            } catch (Exception e) {
                //redisService.setCacheObject(redisfor + "-" + System.currentTimeMillis(), newsSimplePushVO);
                logger.info("push方法http请求异常:{}", e.toString());
            }

            Text2videoJob videoJob = new Text2videoJob();
            videoJob.setBackupText(redisfor);
            videoJob.setTitle(nspVO.getTitle());
            videoJob.setJobId(redisfor);

            if (ObjectUtil.isNotEmpty(httpResponse) && httpResponse.getStatus() == 200) {
                logger.info("单个历史视频任务推送成功,对象:{}", JSONUtil.parseObj(nspVO).toString());
                pushTask.InsertStatSpider(videoJob, 0, httpResponse);
            } else {

                pushTask.InsertStatSpider(videoJob, 1, httpResponse);
                if (ObjectUtil.isNotEmpty(httpResponse) && httpResponse.getStatus() == 505) {
                    logger.info("505状态验证本人操作:{}", nspVO.getUsername());
                    DingUtil.sendMsg("!!! 监控到当前youtube账号验证本人操作", nspVO.getUsername());
                    redisService.setCacheObject(redisfor + "-" + System.currentTimeMillis(), newsSimplePushVO);
                    return;
                } else if (ObjectUtil.isNotEmpty(httpResponse) && httpResponse.getStatus() == 504) {
                    logger.info("504状态已达到每日上传数上限:{},保留视频:{}", nspVO.getUsername(), JSONUtil.parseObj(nspVO).toString());
                    return;
                } else if (ObjectUtil.isNotEmpty(httpResponse) && httpResponse.getStatus() == 503) {
                    logger.info("503状态并发上限，保留视频：{}", JSONUtil.parseObj(nspVO).toString());
                    redisService.setCacheObject(redisfor + "-" + System.currentTimeMillis(), newsSimplePushVO);
                    return;
                } else if (ObjectUtil.isNotEmpty(httpResponse) && httpResponse.getStatus() == 502) {
                    logger.info("502状态当前账号cookie过期:{}", nspVO.getUsername());
                    DingUtil.sendMsg("!!! 监控到当前youtube账号cookie过期", nspVO.getUsername());
                    redisService.setCacheObject(redisfor + "-" + System.currentTimeMillis(), newsSimplePushVO);
                    return;
                } else if (ObjectUtil.isNotEmpty(httpResponse) && httpResponse.getStatus() == 501) {
                    logger.info("501状态当前视频在草稿箱，不需要尝试推送");
                } else {
                    logger.info("500状态删除，频道:{},使用jobId:{},视屏标题:{}", channel, videoJob.getJobId(), videoJob.getTitle());
                }
            }
        }
    }

}